package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
)

// HBaseRESTClient 结构体封装了与 HBase REST Server 交互所需的信息
type HBaseRESTClient struct {
    baseURL string
}

// NewHBaseRESTClient 创建一个新的 HBase REST 客户端实例
func NewHBaseRESTClient(baseURL string) *HBaseRESTClient {
    return &HBaseRESTClient{
        baseURL: baseURL,
    }
}

// CreateTable 创建 HBase 表
func (c *HBaseRESTClient) CreateTable(tableName string, columnFamily string) error {
    url := fmt.Sprintf("%s/%s", c.baseURL, tableName)
    data := []byte(fmt.Sprintf(`{"name":"%s","ColumnSchema":[{"name":"%s"}]}`, tableName, columnFamily))
    req, err := http.NewRequest("PUT", url, bytes.NewBuffer(data))
    if err != nil {
        return err
    }
    req.Header.Set("Content-Type", "application/json")
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return err
    }
    defer resp.Body.Close()
    if resp.StatusCode != http.StatusOK {
        body, _ := ioutil.ReadAll(resp.Body)
        return fmt.Errorf("create table failed: %s", string(body))
    }
    return nil
}

// InsertData 向 HBase 表中插入数据
func (c *HBaseRESTClient) InsertData(tableName, rowKey, columnFamily, columnQualifier, value string) error {
    url := fmt.Sprintf("%s/%s/%s/%s:%s", c.baseURL, tableName, rowKey, columnFamily, columnQualifier)
    data := []byte(value)
    req, err := http.NewRequest("PUT", url, bytes.NewBuffer(data))
    if err != nil {
        return err
    }
    req.Header.Set("Content-Type", "text/plain")
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return err
    }
    defer resp.Body.Close()
    if resp.StatusCode != http.StatusOK {
        body, _ := ioutil.ReadAll(resp.Body)
        return fmt.Errorf("insert data failed: %s", string(body))
    }
    return nil
}

// GetData 从 HBase 表中获取数据
func (c *HBaseRESTClient) GetData(tableName, rowKey, columnFamily, columnQualifier string) (string, error) {
    url := fmt.Sprintf("%s/%s/%s/%s:%s", c.baseURL, tableName, rowKey, columnFamily, columnQualifier)
    resp, err := http.Get(url)
    if err != nil {
        return "", err
    }
    defer resp.Body.Close()
    if resp.StatusCode != http.StatusOK {
        body, _ := ioutil.ReadAll(resp.Body)
        return "", fmt.Errorf("get data failed: %s", string(body))
    }
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return "", err
    }
    var result map[string]interface{}
    err = json.Unmarshal(body, &result)
    if err != nil {
        return "", err
    }
    cell, ok := result["Cell"].([]interface{})
    if!ok || len(cell) == 0 {
        return "", nil
    }
    value, ok := cell[0].(map[string]interface{})["$"].(string)
    if!ok {
        return "", nil
    }
    return value, nil
}

// DeleteData 从 HBase 表中删除数据
func (c *HBaseRESTClient) DeleteData(tableName, rowKey, columnFamily, columnQualifier string) error {
    url := fmt.Sprintf("%s/%s/%s/%s:%s", c.baseURL, tableName, rowKey, columnFamily, columnQualifier)
    req, err := http.NewRequest("DELETE", url, nil)
    if err != nil {
        return err
    }
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return err
    }
    defer resp.Body.Close()
    if resp.StatusCode != http.StatusOK {
        body, _ := ioutil.ReadAll(resp.Body)
        return fmt.Errorf("delete data failed: %s", string(body))
    }
    return nil
}

func main() {
    // 替换为实际的 HBase REST Server 地址
    hbaseRESTURL := "http://2sd802672ff9.vicp.fun:17041"
    client := NewHBaseRESTClient(hbaseRESTURL)

    tableName := "test_table"
    columnFamily := "cf"
    rowKey := "row1"
    columnQualifier := "col1"
    value := "test_value"

    // 创建表
    err := client.CreateTable(tableName, columnFamily)
    if err != nil {
        fmt.Println("Create table error:", err)
        return
    }
    fmt.Println("Table created successfully.")

    // 插入数据
    err = client.InsertData(tableName, rowKey, columnFamily, columnQualifier, value)
    if err != nil {
        fmt.Println("Insert data error:", err)
        return
    }
    fmt.Println("Data inserted successfully.")

    // 获取数据
    data, err := client.GetData(tableName, rowKey, columnFamily, columnQualifier)
    if err != nil {
        fmt.Println("Get data error:", err)
        return
    }
    fmt.Println("Data retrieved:", data)

    // 删除数据
    err = client.DeleteData(tableName, rowKey, columnFamily, columnQualifier)
    if err != nil {
        fmt.Println("Delete data error:", err)
        return
    }
    fmt.Println("Data deleted successfully.")
}
